<!--
 * @Author: aster lipian1004@163.com
 * @Date: 2025-03-24 15:15:12
 * @FilePath: \aster-flowable-uniapp\src\pages\process\process-log.vue
 * @Description: 流程日志
 * Copyright (c) 2025 by Aster, All Rights Reserved.
-->
<template>
  <van-steps direction="vertical" :active="activeNode" class="!py-20rpx">
    <van-step v-for="(log, index) in instanceLogs" :key="index">
      <template #default>
        <view>
          <view>
            <view>{{ getInstanceNodeResult(log)?.nodeName }}</view>
            <span>{{ getInstanceNodeResult(log)?.text }}</span>
            <span
              class="ml-8px"
              v-if="log.length == 1 && isNotEmpty(getInstanceNodeResult(log)?.result)"
            >
              <van-tag type="primary" round class="step-tag">
                {{ getInstanceNodeResult(log)?.result }}
              </van-tag>
            </span>
            <span v-if="log.length == 1" style="font-size: 14px; float: right; color: #606266">
              {{ dateFormat(log[0].finishTime as string, 'YYYY-MM-DD HH:mm') }}
            </span>
          </view>

          <!-- 会签头像 -->
          <view class="step-avatar" v-if="log.length > 1">
            <view v-for="(child, i) in log" :key="i">
              <flow-avatar
                :size="40"
                :avatar="child.user"
                :show-icon="true"
                :icon="getSignIconByItem(child, log)"
                :show-name="true"
              />
            </view>
          </view>

          <view v-for="(child, i) in log" :key="i">
            <!-- 抄送人显示 type==2  -->
            <view v-if="child.type === '2'" class="step-avatar" style="margin-left: -15px">
              <flow-avatar
                v-for="(ccUser, c) in child.ccUsers"
                :key="c"
                :size="40"
                :avatar="ccUser"
                :show-icon="false"
                :show-name="true"
              />
            </view>

            <!-- 任务处理人 -->
            <view class="step-assign" v-if="isNotEmpty(child.taskComments)">
              <view class="comment-content">
                <view v-for="(comment, m) in child.taskComments" :key="m">
                  <view
                    class="step-assign-top"
                    v-if="log.length > 1 || child.taskComments!.length > 1"
                  >
                    <view style="display: flex; flex-direction: row; align-items: center">
                      <flow-avatar
                        :size="30"
                        v-if="child?.user?.avatar"
                        :src="comment?.user?.avatar"
                      />
                      <view style="color: #1989fa; margin-left: -10px">
                        {{
                          isNotEmpty(comment?.user?.realName)
                            ? comment?.user?.realName
                            : comment?.user?.nickName
                        }}
                      </view>
                      <van-tag style="margin-left: 8px" type="primary" round class="step-tag">
                        {{ getApproveName(comment.operationType!.approveType) }}
                      </van-tag>
                    </view>
                    <view style="font-size: 13px">
                      {{ dateFormat(comment.createTime as string, 'MM-DD HH:mm') }}
                    </view>
                  </view>
                  <view
                    class="comment-task"
                    v-if="
                      isNotEmpty(comment?.opinion) ||
                      isNotEmpty(comment?.imageList) ||
                      isNotEmpty(comment?.fileList) ||
                      isNotEmpty(getOperationDesc(comment))
                    "
                  >
                    <view class="comment-task-content">
                      <view>
                        <van-tag v-if="isNotEmpty(getOperationDesc(comment))" class="step-tag">
                          {{ getOperationDesc(comment) }}
                        </van-tag>
                      </view>
                      <view v-if="isNotEmpty(comment?.opinion)">
                        <span>{{ comment?.opinion }}</span>
                      </view>
                      <view class="comment-task-image" v-if="isNotEmpty(comment?.imageList)">
                        <view class="image-preview">
                          <view
                            class="image-list"
                            v-for="(img, g) in comment?.imageList"
                            :key="g"
                            @click="handleImagePreview(img.url)"
                          >
                            <van-image class="image-item" :src="img.url" alt="" />
                          </view>
                        </view>
                      </view>

                      <view class="comment-task-image" v-if="isNotEmpty(comment?.fileList)">
                        <view class="file-preview" v-for="(file, f) in comment?.fileList" :key="f">
                          <view class="file-preview-top">
                            <i class="iconfont icon-fujian px-3px"></i>
                            <span>
                              {{ file.name }}
                            </span>
                          </view>
                          <view class="file-preview-bottom">
                            <span class="pl-20px">
                              <text style="color: #1989fa" @click="handlePreviewFile(file)">
                                预览
                              </text>
                            </span>
                            <span class="pl-20px">
                              <text style="color: #1989fa" @click="handleDownloadFile(file)">
                                下载
                              </text>
                            </span>
                          </view>
                        </view>
                      </view>
                    </view>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </view>
      </template>
    </van-step>
    <van-step v-if="isNotEmpty(lastNode.nodeName)"> </van-step>
  </van-steps>
</template>
<script setup lang="ts">
  import { ProcessButtonTypeEnum, ProcessResultEnum } from '@/enums/workFlowEnum';
  import { isDef, isNotEmpty } from '@/utils/is';
  import {
    dateFormat,
    getApproveName,
    getTaskResult,
    getInstanceNodeResult,
  } from '@/utils/workflow';
  import { computed, PropType, reactive, ref, watchEffect } from 'vue';
  import FlowAvatar from '@/components/process/flow-avatar.vue';
  import { showImagePreview } from 'vant';
  import { downloadFile, previewFile } from '@/utils/fileUtils';

  const props = defineProps({
    logList: {
      type: Object as PropType<WorkForm.ProcessResult>,
      default: () => {},
    },
  });

  // 活动节点
  const activeNode = ref<number>(0);
  // 最后一个节点
  const lastNode = reactive({
    size: '45px',
    iconFont: 'icon-gengduo1',
    nodeName: '',
    color: '',
  });

  /**
   * 流程日志
   */
  const instanceLogs = computed(() => {
    activeNode.value = props.logList.instanceLogs ? props.logList.instanceLogs.length - 1 : 0;
    return props.logList.instanceLogs;
  });

  /**
   * 获取会签头像、图标、icon等
   * @param item
   */
  const getSignIconByItem = (
    item: WorkForm.InstanceLogs,
    instanceLogs: WorkForm.InstanceLogsList,
  ) => {
    // 遍历instanceLogs 查看是否有已完成的任务
    const arr = instanceLogs.filter((item2) => isNotEmpty(item2?.taskComments));
    // OR：或签，AND：会签，ORDER：顺序会签
    if (item.approveType === 'OR') {
      if (arr.length > 0 && isNotEmpty(item.taskComments)) {
        return 'icon-tongyi';
      } else {
        if (arr.length == 0) {
          return 'icon-chulizhong';
        } else {
          return '';
        }
      }
    } else {
      return getTaskResult(item).icon;
    }
  };

  /**
   * 获取任务处理结果描述
   * @param item
   */
  const getOperationDesc = (item?: any) => {
    const operationType = item.operationType;
    if (isNotEmpty(operationType) && isDef(operationType)) {
      switch (operationType.approveType) {
        case ProcessButtonTypeEnum.AGREEN:
          return '';
        case ProcessButtonTypeEnum.DISAGREE:
          return '';
        case ProcessButtonTypeEnum.FORWARD:
          return '转交给：' + operationType.targetName;
        case ProcessButtonTypeEnum.RECALL:
          return '退回到节点：' + operationType.targetName;
        case ProcessButtonTypeEnum.AFTERADDSIGN:
          return '加签给：' + operationType.targetName;
        case ProcessButtonTypeEnum.REVOKE:
          return '';
        case ProcessButtonTypeEnum.SUBMIT:
          return '提交';
        default:
          return '未知操作类型！！！';
      }
    }
  };

  // 图片预览
  const handleImagePreview = (url: string) => {
    showImagePreview([url]);
  };

  // 文件预览
  const handlePreviewFile = (file: any) => {
    previewFile(file.url);
  };

  // 文件下载
  const handleDownloadFile = (file: any) => {
    downloadFile(file.url, file.name);
  };

  watchEffect(() => {
    // 构造最后一个节点，包括流程状态
    if (isNotEmpty(props.logList)) {
      // 获取数组props.instanceLogs的最后一个
      if (props.logList.approveResult === ProcessResultEnum.PROCESSING) {
        lastNode.iconFont = 'icon-gengduo1';
        lastNode.color = '#A8A8A8';
      } else {
        lastNode.iconFont = 'icon-danxuankuang';
        lastNode.color = '#A8A8A8';
      }
      lastNode.size = '30px';
      lastNode.nodeName =
        props.logList.approveResult === ProcessResultEnum.END
          ? '审批通过'
          : (props.logList.approveResultText as string);
    }
  });
</script>
<style scoped lang="scss">
  /*流程title*/
  .step-avatar {
    width: 100%;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    flex-wrap: wrap;
    font-weight: normal;
    margin-top: 15px;
  }
  /*流程办理人*/
  .step-assign {
    margin-top: 15px;
    font-weight: normal;
  }
  .step-assign-top {
    color: #909399;
    font-weight: normal;
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
  }
  .step-tag {
    font-size: 12px !important;
    padding: 2px 10px !important;
  }
  .comment-content {
    display: flex;
    flex-direction: column;
  }
  .comment-task {
    margin-bottom: 15px;
    margin-top: 10px;
    padding: 0 5px;
    display: flex;
    flex-direction: row;
    align-items: center;
    border-radius: 5px;
    border: 1px solid #e4e7ed;
    color: #323233;
  }
  .comment-task-avatar {
    display: flex;
    justify-content: center;
    width: 20%;
  }
  .comment-task-content {
    padding: 5px;
    width: 100%;
    display: flex;
    flex-direction: column;
  }

  .comment-task-image {
    margin: 5px 0;
  }
  .image-preview {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
  }
  .image-list {
    width: 80px;
    height: 80px;
    border: 1px solid #e4e7ed;
    position: relative;
    border-radius: 5px;
    margin: 5px;
  }
  .image-item {
    width: 100%;
    height: 100%;
    border-radius: 5px;
  }

  .image-actions {
    align-items: center;
    background-color: rgba(0, 0, 0, 0.5);
    cursor: default;
    display: inline-flex;
    font-size: 20px;
    height: 100%;
    justify-content: center;
    left: 0;
    opacity: 0;
    position: absolute;
    top: 0;
    width: 100%;
  }
  .image-actions:hover {
    opacity: 1;
    border-radius: 6px;
  }
  .image-actions span {
    cursor: pointer;
    display: none;
  }
  .image-actions:hover span {
    display: inline-flex;
  }

  .file-preview {
    display: flex;
    flex-direction: column;
    border-radius: 4px;
    border: 1px solid #e4e7ed;
    margin: 12px 0;
    padding: 5px;
    .file-preview-top {
      display: -webkit-box; /* 必须配合此属性使用 */
      -webkit-box-orient: vertical; /* 设置为垂直方向 */
      -webkit-line-clamp: 1; /* 显示的行数 */
      overflow: hidden; /* 隐藏超出的内容 */
    }
    .file-preview-bottom {
      padding-top: 10rpx;
      color: #1989fa;
      font-size: 14px;
    }
  }
</style>
